package org.android.demo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.iati.mobile.IATI;
import org.iati.mobile.IATIImpl;
import org.iati.mobile.exception.IATIParseXMLException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.Spinner;

/**
 * @author Ionut Dobre
 * @date April 9, 2012
 */

public class IATIAndroidDemoActivity extends Activity {
	private static final String TAG = "debug";

	private Spinner spinnerDonor;
	private Spinner spinnerSector;
	private Spinner spinnerCountry;
	private Spinner spinnerOrganization;
	private Button GoButton;

	private String selectedDonor;
	private String selectedSector;
	private String selectedCountry;
	private String selectedOrganization;

	private Map<String, String> allDonors;
	private Map<String, String> allSectors;
	private Map<String, String> allCountries;
	private Map<String, String> allOrganizations;

	private IATI mIATI;

	private ProgressDialog progressDialog;
	private String serverURL;
	private String serverPort;
	
	SharedPreferences pref;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// decomment this to allow everything (you shouldn't make network request in the UI thread)
		//StrictMode.enableDefaults();

		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		pref = PreferenceManager.getDefaultSharedPreferences(this);
		serverURL = pref.getString("url", "http://iati-collector.devgw.org");
		serverPort = pref.getString("port", "80");
		

		spinnerDonor = (Spinner) findViewById(R.id.spinnerDonor);
		spinnerSector = (Spinner) findViewById(R.id.spinnerSector);
		spinnerCountry = (Spinner) findViewById(R.id.spinnerCountry);
		spinnerOrganization = (Spinner) findViewById(R.id.spinnerOrganization);

		spinnerDonor.setOnItemSelectedListener(new OnItemSelectedListener () {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
				String selectedItem = parent.getItemAtPosition(pos).toString();

				selectedDonor = "";

				for (Entry<String, String> entry : allDonors.entrySet()) {
					if (entry.getKey() != null && selectedItem.equals(entry.getValue())) {
						selectedDonor = entry.getKey();
					}
				}
			}

			public void onNothingSelected(AdapterView<?> parent) {
				// Do nothing.
			}
		});

		spinnerSector.setOnItemSelectedListener(new OnItemSelectedListener () {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {				
				String selectedItem = parent.getItemAtPosition(pos).toString();

				selectedSector = "";

				for (Entry<String, String> entry : allSectors.entrySet()) {
					if (entry.getKey() != null && selectedItem.equals(entry.getValue())) {
						selectedSector = entry.getKey();
					}
				}
			}

			public void onNothingSelected(AdapterView<?> parent) {
				// Do nothing.
			}
		});

		spinnerCountry.setOnItemSelectedListener(new OnItemSelectedListener () {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {				
				String selectedItem = parent.getItemAtPosition(pos).toString();

				selectedCountry = "";

				for (Entry<String, String> entry : allCountries.entrySet()) {
					if (entry.getKey() != null && selectedItem.equals(entry.getValue())) {
						selectedCountry = entry.getKey();
					}
				}
			}

			public void onNothingSelected(AdapterView<?> parent) {
				// Do nothing.
			}
		});

		spinnerOrganization.setOnItemSelectedListener(new OnItemSelectedListener () {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {				
				String selectedItem = parent.getItemAtPosition(pos).toString();

				selectedOrganization = "";

				for (Entry<String, String> entry : allOrganizations.entrySet()) {
					if (entry.getKey() != null && selectedItem.equals(entry.getValue())) {
						selectedOrganization = entry.getKey();
					}
				}
			}

			public void onNothingSelected(AdapterView<?> parent) {
				// Do nothing.
			}
		});

		GoButton = (Button)findViewById(R.id.go_button);

		GoButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent (IATIAndroidDemoActivity.this, IATIDemoResults.class);
				intent.putExtra("donorID", selectedDonor);
				intent.putExtra("sectorID", selectedSector);
				intent.putExtra("countryID", selectedCountry);
				intent.putExtra("organizationID", selectedOrganization);
				IATIAndroidDemoActivity.this.startActivity(intent);
			}
		});
		
		populateUI();
	}
	
	/*
	 * populate the spinners 
	 */
	private void populateUI() {
		mIATI = new IATIImpl(serverURL, serverPort);
		
		// populate the spinners (the network operations are executed in a new thread)
		final Runnable runnableDonors = new Runnable() {
			public void run() {
				try {
					
					allDonors = mIATI.getAllDonors();
					
					// remove the empty entries
					Iterator<Entry<String, String>> entries = allDonors.entrySet().iterator();
					while (entries.hasNext()) {
						Entry<String, String> mEntry = entries.next();
						if (mEntry.getKey() == null ||  mEntry.getValue() == null) {
							entries.remove();
						}
					}
					
					LinkedHashMap<String, String> tempMap	= new LinkedHashMap<String, String>(allDonors.size() + 1);
					tempMap.put("-1", "<Select>");
					tempMap.putAll(allDonors);
					allDonors	= tempMap;
					
					// update the UI
					runOnUiThread(new Runnable() {
						public void run() {
							ArrayList<String> sectors = new ArrayList<String>(allDonors.values());
							MyAdapter adapter = new MyAdapter(sectors, IATIAndroidDemoActivity.this);
							spinnerDonor.setAdapter(adapter);
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				} catch (IATIParseXMLException e) {
					e.printStackTrace();
				}
			}
		};

		final Runnable runnableSectors = new Runnable() {
			public void run() {
				try {
					allSectors = mIATI.getAllSectors();
					
					// remove the empty entries
					Iterator<Entry<String, String>> entries = allSectors.entrySet().iterator();
					while (entries.hasNext()) {
						Entry<String, String> mEntry = entries.next();
						if (mEntry.getKey() == null ||  mEntry.getValue() == null) {
							entries.remove();
						}
					}
					

					LinkedHashMap<String, String> tempMap	= new LinkedHashMap<String, String>(allSectors.size() + 1);
					tempMap.put("-1", "<Select>");
					tempMap.putAll(allSectors);
					allSectors	= tempMap;

					// update the UI
					runOnUiThread(new Runnable() {
						public void run() {
							ArrayList<String> sectors = new ArrayList<String>(allSectors.values());
							MyAdapter adapter = new MyAdapter(sectors, IATIAndroidDemoActivity.this);
							spinnerSector.setAdapter(adapter);
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				} catch (IATIParseXMLException e) {
					e.printStackTrace();
				}
			}
		};

		final Runnable runnableCountries = new Runnable() {
			public void run() {
				try {
					allCountries = mIATI.getAllRecipientCountries();
					
					// remove the empty entries
					Iterator<Entry<String, String>> entries = allCountries.entrySet().iterator();
					while (entries.hasNext()) {
						Entry<String, String> mEntry = entries.next();
						if (mEntry.getKey() == null ||  mEntry.getValue() == null) {
							entries.remove();
						}
					}

					LinkedHashMap<String, String> tempMap	= new LinkedHashMap<String, String>(allCountries.size() + 1);
					tempMap.put("-1", "<Select>");
					tempMap.putAll(allCountries);
					allCountries	= tempMap;
					
					// update the UI
					runOnUiThread(new Runnable() {
						public void run() {
							ArrayList<String> sectors = new ArrayList<String>(allCountries.values());
							MyAdapter adapter = new MyAdapter(sectors, IATIAndroidDemoActivity.this);
							spinnerCountry.setAdapter(adapter);
						}
					});

					// dismiss the progress dialog
					if(progressDialog != null) 
						progressDialog.dismiss();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (IATIParseXMLException e) {
					e.printStackTrace();
				}
			}
		};

		final Runnable runnableOrganizations = new Runnable() {
			public void run() {
				try {
					allOrganizations = mIATI.getAllReportingOrganizations();
					
					// remove the empty entries
					Iterator<Entry<String, String>> entries = allOrganizations.entrySet().iterator();
					while (entries.hasNext()) {
						Entry<String, String> mEntry = entries.next();
						if (mEntry.getKey() == null ||  mEntry.getValue() == null) {
							entries.remove();
						}
					}

					LinkedHashMap<String, String> tempMap	= new LinkedHashMap<String, String>(allOrganizations.size() + 1);
					tempMap.put("-1", "<Select>");
					tempMap.putAll(allOrganizations);
					allOrganizations	= tempMap;
					
					// update the UI
					runOnUiThread(new Runnable() {
						public void run() {
							ArrayList<String> sectors = new ArrayList<String>(allOrganizations.values());
							MyAdapter adapter = new MyAdapter(sectors, IATIAndroidDemoActivity.this);
							spinnerOrganization.setAdapter(adapter);
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				} catch (IATIParseXMLException e) {
					e.printStackTrace();
				}
			}
		};

		// show the progress dialog
		progressDialog = ProgressDialog.show(IATIAndroidDemoActivity.this, "", "Loading...", true, true);

		// run on background thread.
		performOnBackgroundThread(runnableDonors);
		performOnBackgroundThread(runnableSectors);
		performOnBackgroundThread(runnableCountries);
		performOnBackgroundThread(runnableOrganizations);
	}

	/**
	 * Executes the network requests on a separate thread.
	 * 
	 * @param runnable The runnable instance containing network operations to be executed.
	 */
	public static Thread performOnBackgroundThread(final Runnable runnable) {
		final Thread mThread = new Thread() {
			@Override
			public void run() {
				try {
					runnable.run();
				} finally {
					// ...
				}
			}
		};
		mThread.start();
		return mThread;
	}
	
	public void onResume() {
		super.onResume();
		
		// get the server url and the server port
		serverURL = pref.getString("url", "http://iati-collector.devgw.org");
		serverPort = pref.getString("port", "80");
		
		Log.d(TAG, "serverURL: " + serverURL);
		Log.d(TAG, "serverPort: " + serverPort);
	}
	
	/*
	 * Create Menu Option
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.options_menu_dashboard, menu);
		return true;
	}
	
	/*
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.dashboard_refresh:
			populateUI();

			return true;
		case R.id.dashboard_settings:
			Intent settingsIntent = new Intent (IATIAndroidDemoActivity.this, SettingsActivity.class);
			IATIAndroidDemoActivity.this.startActivity(settingsIntent);

			return true;
		default:
			return false;
		}
	}
}